package com.jingbit.ai.bt;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.util.Log;

public class BluetoothUtil {
    private static final String TAG = "jingbit";

    /**
     * 角度转pwm值
     * @param angle
     * @param mid
     * @return
     */
    public static int angleToPwm(int angle, float mid) {
        return (int) (((mid - angle) / mid) * 157f);
    }

    /**
     * pwm转角度值
     * @param pwm
     * @param mid
     * @return
     */
    public static int pwmToAngle(int pwm, float mid) {
        return (int) ((pwm / 157f * mid) - mid);
    }

    public static int getAngleIndex(String name) {
        for (int i = 0; i < BluetoothService.ANGLE_NS.length; i++) {
            if (BluetoothService.ANGLE_NS[i].equals(name)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * int到byte[]
     *
     * @param num
     * @return
     */
    public static byte[] intToByteArray(int num) {
        int i = Math.abs(num);
        byte[] result = new byte[4];
        //由高位到低位
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        Log.d(TAG, "intToByteArray： " + num + "---" + Arrays.toString(result));
        return result;
    }

    /**
     * byte[]转int
     *
     * @param bytes
     * @return
     */
    public static int byteArrayToInt(byte[] bytes) {
        int value = 0;
        //由高位到低位
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (bytes[i] & 0x000000FF) << shift;//往高位游
        }
        return value;
    }

    public static BluetoothDevice pair(String strAddr, String strPsw)
    {
        boolean result = false;
        //蓝牙设备适配器
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter
                .getDefaultAdapter();
        //取消发现当前设备的过程
        bluetoothAdapter.cancelDiscovery();
        if (!bluetoothAdapter.isEnabled())
        {
            bluetoothAdapter.enable();
        }
        if (!BluetoothAdapter.checkBluetoothAddress(strAddr))
        { // 检查蓝牙地址是否有效
            Log.d(TAG, "devAdd un effient!");
        }
        //由蓝牙设备地址获得另一蓝牙设备对象
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(strAddr);
        if (device.getBondState() != BluetoothDevice.BOND_BONDED)
        {
            try
            {
                Log.d(TAG, "NOT BOND_BONDED");
                setPin(device.getClass(), device, strPsw); // 手机和蓝牙采集器配对
                createBond(device.getClass(), device);
                //    ClsUtils.cancelPairingUserInput(device.getClass(), device);
//                remoteDevice = device; // 配对完毕就把这个设备对象传给全局的remoteDevice
                result = true;
            }
            catch (Exception e)
            {
                Log.d(TAG, "setPiN failed!");
                e.printStackTrace();
            }
        }
        else
        {
            Log.d(TAG, "HAS BOND_BONDED");
            try
            {
                //ClsUtils这个类的的以下静态方法都是通过反射机制得到需要的方法
                createBond(device.getClass(), device);//创建绑定
                setPin(device.getClass(), device, strPsw); // 手机和蓝牙采集器配对
                createBond(device.getClass(), device);
                //    ClsUtils.cancelPairingUserInput(device.getClass(), device);
//                remoteDevice = device; // 如果绑定成功，就直接把这个设备对象传给全局的remoteDevice
                result = true;
            }
            catch (Exception e)
            {
                Log.d(TAG, "setPiN failed!");
                e.printStackTrace();
            }
        }
        return result?device:null;
    }

    /**
     * 与设备配对 参考源码：platform/packages/apps/Settings.git
     * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
     */
    static public boolean createBond(Class btClass, BluetoothDevice btDevice)
            throws Exception {
        Method createBondMethod = btClass.getMethod("createBond");
        Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
        return returnValue.booleanValue();
    }

    /**
     * 与设备解除配对 参考源码：platform/packages/apps/Settings.git
     * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
     */
    static public boolean removeBond(Class btClass, BluetoothDevice btDevice)
            throws Exception {
        Method removeBondMethod = btClass.getMethod("removeBond");
        Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
        return returnValue.booleanValue();
    }

    static public boolean setPin(Class btClass, BluetoothDevice btDevice,
                                 String str) throws Exception {
        try {
            Method removeBondMethod = btClass.getDeclaredMethod("setPin",
                    byte[].class);
            Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
                    new Object[]
                            {str.getBytes()});
            Log.e("returnValue", "" + returnValue);
        } catch (SecurityException e) {
            // throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;

    }

    // 取消用户输入
    static public boolean cancelPairingUserInput(Class btClass,
                                                 BluetoothDevice device)

            throws Exception {
        Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
        // cancelBondProcess()
        Boolean returnValue = (Boolean) createBondMethod.invoke(device);
        return returnValue.booleanValue();
    }

    // 取消配对
    static public boolean cancelBondProcess(Class btClass,
                                            BluetoothDevice device)

            throws Exception {
        Method createBondMethod = btClass.getMethod("cancelBondProcess");
        Boolean returnValue = (Boolean) createBondMethod.invoke(device);
        return returnValue.booleanValue();
    }

    /**
     * @param clsShow
     */
    static public void printAllInform(Class clsShow) {
        try {
            // 取得所有方法
            Method[] hideMethod = clsShow.getMethods();
            int i = 0;
            for (; i < hideMethod.length; i++) {
                Log.e("method name", hideMethod[i].getName() + ";and the i is:"
                        + i);
            }
            // 取得所有常量
            Field[] allFields = clsShow.getFields();
            for (i = 0; i < allFields.length; i++) {
                Log.e("Field name", allFields[i].getName());
            }
        } catch (SecurityException e) {
            // throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //确认配对
    static public void setPairingConfirmation(Class<?> btClass, BluetoothDevice device, boolean isConfirm) throws Exception {
        Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation", boolean.class);
        setPairingConfirmation.invoke(device, isConfirm);
    }
}